import { OnInit, Component, Injector, ViewChild, TemplateRef } from "@angular/core";
import { BaseController } from "@shared/base-controller";
import { GroupService } from "../../../service/group/group.service";
import { catchError } from "rxjs/operators";
import { of } from "rxjs";
import { NzTreeNode, NzFormatEmitEvent, NzMessageService, NzModalRef, NzModalService, NzDropdownService, NzDropdownContextComponent } from "ng-zorro-antd";
import { FormGroup, FormControl, Validators } from "@angular/forms";
import { AuthModalComponent } from "@shared/component/auth/auth-modal.component";
import { GroupMemberModalComponent } from "./member/group-member-modal.component";
import { AuthorizeModalComponent } from "@shared/component/authorize/authorize-modal.component";
import { Constant } from "@core/constant";
import { SimpleTableColumn, SimpleTableComponent, SimpleTableButton } from "@delon/abc";
import { UserSelectModalComponent } from "@shared/component/users/user-select-modal.component";
import { UserSelectModalV2Component } from "@shared/component/users2/user-select-modal.component";

@Component({
    selector: 'app-group-list',
    templateUrl: './group.component.html',
    styleUrls: []
  })
export class GroupComponent extends BaseController implements OnInit {
    loading = false;
    
    searchValue;

    // 分类节点集合
    nodes = [];    
    // 当前被选中的节点
    currentNode = null;

    // 表单
    groupForm;
    // 编辑状态
    editStatus;
    formStatus;
    confirmModal: NzModalRef; 
    showMember = true;
    addBtn = true;
    editBtn = true;
    delBtn = true;
    userBtn = true;
    authBtn = true;
    authMenuBtn = true;
    dropdown: NzDropdownContextComponent;

    ps = 10;
    q: any = {
        groupId: "-1"
    };
    url = this.group.getGroupMemberUrl();
    data = [];
    @ViewChild('st') st: SimpleTableComponent;

    columns: SimpleTableColumn[] = [                  
        { title: '账号', index: 'username'},            
        { title: '名称', index: 'name' },        
        { 
            title: '操作',
            buttons: [              
                {
                    text: '删除',
                    type: 'del',                   
                    click: (record: any) =>this.delGroupMember(record.id)
                }
            ],
            fixed: 'right',
            width: '100px'
        }        
    ];

    constructor(
        public injector: Injector,
        private group: GroupService,
        public msg: NzMessageService,
        private modalService: NzModalService,
        private cnt: Constant,
        private nzDropdownService: NzDropdownService
    ) {
        super(injector);
    }

    ngOnInit() {       
        this.loadGroupType();
        this.loadGroup();
    }

    loadGroupType() {        
        this.groupForm = new FormGroup({
            name     : new FormControl({value: null, disabled: !this.editStatus}, Validators.required),
            code     : new FormControl({value: null, disabled: !this.editStatus}, Validators.required),                    
            description : new FormControl({value: null, disabled: !this.editStatus}),                   
            id           : new FormControl({value: null, disabled: !this.editStatus}),
            parentId     : new FormControl({value: -1, disabled: !this.editStatus}),
            groupType     : new FormControl({value: 'role', disabled: !this.editStatus})
        }); 
    }

    loadGroup(force = false) {
        if (this.nodes.length != 0 && !force) {
            return;
        }
        this.group.getGroups('role').pipe(
            catchError(err => {
                return of(err);
            })
        ).subscribe(data => {
            this.nodes = [];
            let o = this.replaceKeysDeep(data, this.mapShortToLong);            
            for (let index = 0; index < o.length; index++) {
                this.nodes.push(
                    new NzTreeNode(o[index])
                );
            }   
        }) 
    }

    mapShortToLong: any = {
        "id": "key",
        "label": "title"
    };

 

    /**
     * 节点单击处理事件
     * @param name 
     * @param e 
     */
    mouseAction(name: string, e: NzFormatEmitEvent): void {        
        if (name === 'click') {            
            if (e.node.isSelected) {   
                // 如果当前是编辑状态, 则选中一个节点,按钮应该确保是更新按钮
                if (this.editStatus) {
                    this.formStatus = 'update';
                }                       
                this.currentNode = e.node;                   
                // 获取详情       
                this.group.getDetail(e.node.key).pipe(
                    catchError(err => {
                        return of(err);
                    })
                ).subscribe(data => {            
                    if (data.status === 200) {
                        this.setFormValue(data.data); 
                        this.showMember = true;                       
                        // if (data.data.code === 'sms_cloud') {
                        //     this.showMember = false;
                        // } else {
                            // this.showMember = true;
                        // }
                    } else {
                        this.msg.error(data.message);
                    }
                })
                this.q.groupId = e.node.key;
                this.st.load(1, this.q);
                
            } else {
                this.resetNode();  
                this.cancel();          
                this.q.groupId = '-1';
                this.st._data = [];         
            }
        } 
    }

    cancel() {
        this.editStatus = false;
        this.disableForm();
        if (this.formStatus === 'create') {
          this.resetForm();
        }
    }

    resetNode() {
        this.currentNode = null;    
        this.resetForm();
    }

    resetForm() {
        for (const i in this.groupForm.controls) {
            this.groupForm.controls[ i ].reset();  
        }        
        this.groupForm.get('parentId').setValue("-1");
        this.groupForm.get('groupType').setValue('role');
    }

    setFormValue(node) {
        this.resetForm();
        this.groupForm.patchValue(node);
    }  

    enableForm() {
        for (const i in this.groupForm.controls) {
            this.groupForm.controls[ i ].enable();  
        }
    }

    disableForm() {    
        for (const i in this.groupForm.controls) {
            this.groupForm.controls[ i ].disable();  
        }
    }

    /**
     * 添加
     */
    add(): void { 
        if (this.formStatus == 'update' && this.editStatus) {
            this.msg.warning('有未提交的表单, 请确定是否保存');
            return;
        }        
        this.resetForm();
        this.enableForm();
        this.formStatus = 'create';
        this.editStatus = true;
        if (this.currentNode) {
            this.groupForm.get('parentId').setValue(this.currentNode.key);
        } else {
            this.groupForm.get('parentId').setValue('-1');
        }    
    }

    doAdd() {
        for (const i in this.groupForm.controls) {
            this.groupForm.controls[ i ].markAsDirty();
            this.groupForm.controls[ i ].updateValueAndValidity();
        }        
        
        if (this.groupForm.get('name').dirty && this.groupForm.get('name').errors) {
            this.msg.warning('请填写名称');
            return;
        }    
        if (this.groupForm.get('code').dirty && this.groupForm.get('code').errors) {
            this.msg.warning('请填写编码');
            return;
        } 
    }

    edit(code) {
      if (this.formStatus == 'create' && this.editStatus) {
          this.msg.warning('有未提交的表单, 请确定是否保存');
          return;
      } 
      if (!this.currentNode) {
          this.msg.warning('请选择一个角色');
          return;
      }
      this.editStatus = true;
      this.enableForm();
      this.formStatus = 'update';
      if (!this.groupForm.get('id').value) {
          // 获取详情       
          this.group.getDetail(this.currentNode.key).pipe(
                catchError(err => {
                    return of(err);
                })
            ).subscribe(data => {            
                if (data.status === 200) {
                    this.setFormValue(data.data);                
                } else {
                    this.msg.error(data.message);
                }
            })
      }
    }


    doEdit(): void {
        for (const i in this.groupForm.controls) {
            this.groupForm.controls[ i ].markAsDirty();
            this.groupForm.controls[ i ].updateValueAndValidity();
        }    
        if (this.groupForm.get('name').dirty && this.groupForm.get('name').errors) {
            this.msg.warning('请填写名称');
            return;
        }       
        if (this.groupForm.get('code').dirty && this.groupForm.get('code').errors) {
            this.msg.warning('请填写编码');
            return;
        }
         
        if (this.groupForm.valid) {
            let v = this.groupForm.value;          
            if (v.code === 'sms_cloud') {
                this.msg.warning("基础角色无法编辑");
                return;
            }
            this.loading = true;            
            this.callEdit(v);
        }
    }

    callEdit(v) {
        if (this.formStatus === 'update') {                      
            this.group.modifyGroup(v).pipe(
                catchError(err => {                             
                    return of(err);
                })
            ).subscribe(data => {
                this.loading = false;
                if (data['status'] && data['status'] === 200) {                
                    this.loadGroup(true);
                    this.msg.success('操作成功');
                } else {
                    this.msg.error('操作失败' + data['message']);
                }
            })
        } else {
            this.group.addGroup(v).pipe(
                catchError(err => {                             
                    return of(err);
                })
            ).subscribe(data => {
                this.loading = false;
                if (data['status'] && data['status'] === 200) {                
                    this.loadGroup(true);              
                    this.msg.success('操作成功');
                } else {
                    this.msg.error('操作失败' + data['message']);
                }
            })
        }
    }

    del() {
        
        if (this.groupForm.get('code').value == 'sms_cloud') {
            this.msg.warning("基础角色无法删除");
            return ;
        }

        if (this.currentNode) {
            this.confirmModal = this.modalService.confirm({
                nzTitle: `删除提醒`,
                nzContent: `你确定删除角色 ${this.currentNode.title} ?`,
                nzOnOk: () => {
                    this.doDel();
                }
            });
            
        } else {
            this.msg.warning('请选择要删除的角色');
        } 
    }

    doDel() {
        this.group.delGroup(this.currentNode.key).pipe(
            catchError(err => {                             
                return of(err);
            })
        ).subscribe(ret => {
            if (ret.status === 200) {
                this.resetNode();
                this.loadGroup(true);     
            } else {
                this.msg.error(ret.message);
            }
        });
    }

    authSelect() {
        if (!this.currentNode) {
            this.msg.warning('请选择角色');
            return;
        }

        // if (this.groupForm.get('code').value == 'sms_cloud') {
        //     this.msg.error("基础角色无法修改");
        //     return ;
        // }

        const modal = this.modalService.create({
            nzContent: AuthModalComponent,
            nzStyle: {"top": "24px"},
            nzWidth: 900,
            nzFooter: null,
            nzComponentParams: { groupId: this.currentNode.key }
        }); 
        modal.afterOpen.subscribe(() => {
            modal.getContentComponent().getSubject().subscribe(data => {
                let table: Array<any> = data as Array<any>;
                let list = table.map(v => {
                    return v.key;
                })                
                this.group.addGroupMenu(this.currentNode.key, list.toString()).pipe(
                    catchError(err => {
                        return of(err)
                    })
                ).subscribe(data => {
                    if (data.status === 200) {
                        this.msg.success('操作成功');
                    } else {
                        this.msg.error('操作失败' + data.message);
                    }
                })
            })
        })
    }

    authorizeSelect() {
        if (!this.currentNode) {
            this.msg.warning('请选择角色');
            return;
        }
        const modal = this.modalService.create({
            nzContent: AuthorizeModalComponent,
            nzStyle: {"top": "24px"},
            nzWidth: 900,
            nzFooter: null,
            nzComponentParams: { groupId: this.currentNode.key }
        }); 
        modal.afterOpen.subscribe(() => {
            modal.getContentComponent().getSubject().subscribe(data => {
                let table: Array<any> = data as Array<any>;
                let list = table.map(v => {
                    return v.key;
                })                
                this.group.addGroupAuthorizeMenu(this.currentNode.key, list.toString()).pipe(
                    catchError(err => {
                        return of(err)
                    })
                ).subscribe(data => {
                    if (data.status === 200) {
                        this.msg.success('操作成功');
                    } else {
                        this.msg.error('操作失败' + data.message);
                    }
                })
            })
        })
    }

    memberSelect() {
        if (!this.currentNode) {
            this.msg.warning('请选择角色');
            return;
        }
        const modal = this.modalService.create({
            nzContent: GroupMemberModalComponent,
            nzStyle: {"top": "24px"},            
            nzFooter: null,
            nzComponentParams: { groupId: this.currentNode.key }
        }); 
        modal.afterOpen.subscribe(() => {
            modal.getContentComponent().getSubject().subscribe(data => {
                this.group.putGroupMembers(this.currentNode.key, data).pipe(
                    catchError(err => {                             
                        return of(err);
                    })
                ).subscribe(data => {  
                    if (data.status === 200) {
                        this.msg.success('操作成功');                         
                    } else {
                        this.msg.error(data['message']);
                    }
                });
            })
        })
    }

    delGroupMember(id) {
        this.group.delGroupMember(this.currentNode.key, id).pipe(
            catchError(err => {
                return of(err)
            })
        ).subscribe(data => {
            if (data.status === 200) {
                this.st.load(1, this.q);         
            } else {
                this.msg.error(data.message);
            }
        })
    }

    openUserDialog() {    
        if (!this.currentNode) {
          this.msg.warning('请选择角色');
          return;
        }
        const modal = this.modalService.create({
            nzContent: UserSelectModalComponent,
            nzWidth: '730px',            
            nzFooter: null
        }); 
        modal.afterOpen.subscribe(() => {
            modal.getContentComponent().getSubject().subscribe(data => {
                let users = data as Array<any>;            
                this.group.addGroupMember(this.currentNode.key, users.toString()).pipe(
                  catchError(err => {
                    return of(err);
                  }) 
                ).subscribe(data => {
                  if (data['status'] === 200) {
                    this.msg.success("操作成功");                  
                  } else {
                    this.msg.error("操作失败: 重复添加");
                  }
                  this.st.load(1, this.q);
                });
            })
        })
    }

    openUserDialog2() {    
        if (!this.currentNode) {
          this.msg.warning('请选择角色');
          return;
        }
        const modal = this.modalService.create({
            nzContent: UserSelectModalV2Component,            
            nzFooter: null
        }); 
        modal.afterOpen.subscribe(() => {
            modal.getContentComponent().getSubject().subscribe(data => {
                let users = data as Array<any>;            
                this.group.addGroupMember(this.currentNode.key, users.toString()).pipe(
                  catchError(err => {
                    return of(err);
                  }) 
                ).subscribe(data => {
                  if (data['status'] === 200) {
                    this.msg.success("操作成功");                  
                  } else {
                    this.msg.error("操作失败: 重复添加");
                  }
                  this.st.load(1, this.q);
                });
            })
        })
    }

    contextMenu($event, template: TemplateRef<void>): void {
        if (this.currentNode) {
            this.currentNode.isSelected = false;
        }
        $event.node.isSelected = true;
        this.currentNode = $event.node;
        
        // 如果当前是编辑状态, 则选中一个节点,按钮应该确保是更新按钮
        if (this.editStatus) {
            this.formStatus = 'update';
        }                       
        // 获取详情       
        this.group.getDetail(this.currentNode.key).pipe(
            catchError(err => {
                return of(err);
            })
        ).subscribe(data => {            
            if (data.status === 200) {
                this.setFormValue(data.data);
                this.showMember = true;                        
                // if (data.data.code === 'sms_cloud') {
                //     this.showMember = false;
                // } else {
                //     this.showMember = true;
                // }
            } else {
                this.msg.error(data.message);
            }
        })
        this.q.groupId = this.currentNode.key;
        if (this.st) {
            this.st.load(1, this.q);
        }
        this.dropdown = this.nzDropdownService.create($event.event, template);
    }
}